#pragma once

#include "types.h"
#include <string>

class ProblemsContainerBase
{
public:
	static const RetType UNIMPLEMENTED = static_cast<RetType>(0xdeadbeef);

	ProblemsContainerBase();

	const std::string& GetName() const;
	RetType SolveProblem(const UInt i_problemNumber) const;

	//override these if you need
	virtual ~ProblemsContainerBase();
	virtual bool Shutdown();

	//you must override these
	virtual bool Init(Register& o_register) = 0;

protected:
	void RegisterFunc(Register& o_register, const UInt i_number, ProblemFunctor i_functor);
	std::string m_name;

private:
	ProblemMap m_problemMap;
};

#define REGISTER_FUNC(name, n1) RegisterFunc(o_register, n1, &name##::Problem##n1);
#define REGISTER_FUNC2(name, n1, n2) REGISTER_FUNC(name, n1) REGISTER_FUNC(name, n2)
#define REGISTER_FUNC3(name, n1, n2, n3) REGISTER_FUNC2(name, n1, n2) REGISTER_FUNC(name, n3)
#define REGISTER_FUNC4(name, n1, n2, n3, n4) REGISTER_FUNC3(name, n1, n2, n3) REGISTER_FUNC(name, n4)
#define REGISTER_FUNC5(name, n1, n2, n3, n4, n5) REGISTER_FUNC4(name, n1, n2, n3, n4) REGISTER_FUNC(name, n5)
#define REGISTER_FUNC6(name, n1, n2, n3, n4, n5, n6) REGISTER_FUNC5(name, n1, n2, n3, n4, n5) REGISTER_FUNC(name, n6)
#define REGISTER_FUNC7(name, n1, n2, n3, n4, n5, n6, n7) REGISTER_FUNC6(name, n1, n2, n3, n4, n5, n6) REGISTER_FUNC(name, n7)
#define REGISTER_FUNC8(name, n1, n2, n3, n4, n5, n6, n7, n8) REGISTER_FUNC7(name, n1, n2, n3, n4, n5, n6, n7) REGISTER_FUNC(name, n8)

